package labox.innovation.gameserver.skills;

import java.io.File;
import java.util.List;

import javolution.util.FastList;
import labox.innovation.config.Config;
import labox.innovation.gameserver.model.L2Skill;
import labox.innovation.gameserver.skills.conditions.Condition;
import labox.innovation.gameserver.skills.effects.EffectChanceSkillTrigger;
import labox.innovation.gameserver.templates.StatsSet;
import labox.innovation.gameserver.templates.skills.L2SkillType;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;

/**
 *  ���ܽ�����
 * @author zjj
 *
 */
class DocumentSkill extends DocumentBase {

    public class Skill
    {
        public int                  id;
        public String               name;
        //ÿ�����ܶ��кܶ��ȼ� �� ǿ���ȼ� 
        //StateSet����ÿ�����ܻ�ȼ� �� ǿ���ȼ��� ���ԣ���:�˺��ȣ�
        public StatsSet[]           sets;        
        //
        public int                  currentLevel;
        
        //����ļ����б�
        public List<L2Skill>   skills          = new FastList<L2Skill>();
        public List<L2Skill>   currentSkills   = new FastList<L2Skill>();
    }

    private Skill _currentSkill;
    private List<L2Skill> _skillsInFile  = new FastList<L2Skill>();

	DocumentSkill(File file)
	{
		super(file);
	}

    private void setCurrentSkill(Skill skill)
    {
        _currentSkill    = skill;
    }

    @Override
	public StatsSet getStatsSet()
	{
		return _currentSkill.sets[_currentSkill.currentLevel];
	}

	protected List<L2Skill> getSkills()
	{
        return _skillsInFile;
	}

	@Override
	public String getTableValue(String name)
	{
		try
        {
            return _tables.get(name)[_currentSkill.currentLevel];
        }
		catch (RuntimeException e)
        {
			Object [] temp = {name, _currentSkill.id, e};
            _log.error("Error in table of Skill  " + temp, Config.SERVER_ID, e );
            return "";
        }
	}

	@Override
	//��ñ��� idx��ֵ
	public String getTableValue(String name, int idx)
	{
		try
        {
            return _tables.get(name)[idx-1];
        }
		catch (RuntimeException e)
        {
			Object [] temp = { _currentSkill.id, e};
            _log.error("wrong level count in skill  " + temp, Config.SERVER_ID, e );
            return "";
        }
	}

	@Override
	public void parseDocument(Document doc)
	{   
        //new 
        //�µ� ����xml�ķ���.
        NodeList skillList = doc.getElementsByTagName( "skill" );
        int iLength = skillList.getLength();
        
        for( int i = 0; i < iLength; i++ )
        {
        	Element skillEl = (Element) skillList.item( i );
        	setCurrentSkill(new Skill());
        	parseSkill( skillEl );
            _skillsInFile.addAll(_currentSkill.skills);
            resetTable();
        }
        
	}// end parseDocument

    protected void parseSkill(Node n)
	{
    	try {
			
    		//begine ���ܽڵ����������
        	NamedNodeMap attrs = n.getAttributes();
            
    		int skillId = Integer.parseInt(attrs.getNamedItem("id").getNodeValue());
    		
    		String skillName = attrs.getNamedItem("name").getNodeValue();
    		String level = attrs.getNamedItem("level").getNodeValue();
    		
    		//���ܵȼ�
    		int skillLvl = Integer.parseInt(level);
    		//�������ӵ�еĵȼ�
    		int lastLvl = 1;
    		if( attrs.getNamedItem("levels") != null )
    		{
    			level = attrs.getNamedItem("levels").getNodeValue();
    			lastLvl = Integer.parseInt(level);
    		}
    	

            _currentSkill.id     = skillId;
            _currentSkill.name   = skillName;
            _currentSkill.sets   = new StatsSet[lastLvl];

    		for (int i=0; i < lastLvl; i++)
    		{
                _currentSkill.sets[i] = new StatsSet();
                _currentSkill.sets[i].set("skill_id", _currentSkill.id);
//                _currentSkill.sets[i].set("level",    i+1);
                _currentSkill.sets[i].set("level",    skillLvl);
                _currentSkill.sets[i].set("name",     _currentSkill.name);
    		}

    		if (_currentSkill.sets.length != lastLvl)
    			throw new RuntimeException("Skill id="+skillId+" number of levels missmatch, "+lastLvl+" levels expected");
    		
    	    //end ���ܽڵ����������
    		
    		//�������еı�
    		//������ݵĲ�ѯ�Ա�Ϊǰ��
    		
    		//new 
    		NodeList tableList = ( (Element)n ).getElementsByTagName("table");
    		for( int i = 0; i < tableList.getLength(); i++ )
    		{
    			parseTable( tableList.item(i) );
    		}
    		// new 
    		
    		//�������ܵ�����
    		
    		//new
    		NodeList setList = ( (Element)n ).getElementsByTagName("set");
    		//���ܷ�ǿ���ĵȼ� �������
    		for( int i=1; i <= lastLvl; i++ )
    		{
    			for( int j=0; setList!=null && j < setList.getLength(); j++ )
    			{
    				parseBeanSet( setList.item( j ), _currentSkill.sets[i-1], i );
    			}
    			
    		}
    		//new 
    		
            /***/
            
            //�ϳ����м��ܵȼ�
            //��ɵ�ǰ���ܵ����м��ܵȼ�
            makeSkills();
            
            _currentSkill.currentLevel = skillLvl;
            
           //����������������� ���ܵ��������Ե�
            NodeList condList = ( (Element)n ).getElementsByTagName("cond");
            NodeList forList  = ( (Element)n ).getElementsByTagName("for");
    		for (int i=0; i < lastLvl; i++)
    		{
//                _currentSkill.currentLevel = i;
    		
                //�������ܵ����������������ӵ���������           
                //
                for( int j=0; j < condList.getLength(); j++ )
                {
                	attchCond( _currentSkill.currentSkills.get(i), condList.item(j) );
                	
                }// end for condlist
                
                for( int j=0; j < forList.getLength(); j++ )
                {
                	parseTemplate( forList.item( j ), _currentSkill.currentSkills.get(i) );
                }
    			
    		}//end for(int i=0; i < lastLvl; i++)
    		
            _currentSkill.skills.addAll(_currentSkill.currentSkills);
    		
		} catch (Exception e) {
			e.printStackTrace();
		}

		
        
	}// end parseSkill
    
    /**
     * ���Ӽ������� cond
     * @param skill
     * @param node
     */
    private void attchCond( L2Skill skill, Node node )
    {
    	Condition condition = parseCondition( node.getFirstChild() , skill );
    	Node msg = node.getAttributes().getNamedItem("msg");
    	Node msgId = node.getAttributes().getNamedItem("msgId");
    	if (condition != null && msg != null)
    	{
    		condition.setMessage(msg.getNodeValue());
    	}
    	else if (condition != null && msgId != null)
		{
			condition.setMessageId( Integer.decode( getValue( msgId.getNodeValue(), null ) ) );
			Node addName = node.getAttributes().getNamedItem( "addName" );
			if (addName != null && Integer.decode(getValue(msgId.getNodeValue(), null)) > 0)
				condition.addName();
		}
    	//���Ӽ��ܵ���������
    	skill.attach( condition, false );
    }

    private void makeSkills()
	{
        int count = 0;
        //�ܹ��ļ��ܵȼ���
        _currentSkill.currentSkills = new FastList<L2Skill>(_currentSkill.sets.length);

        //��ͨ���ܵȼ�
        //Ϊÿ�����ܵȼ����һ�����ܶ���
		for (int i=0; i < _currentSkill.sets.length; i++)
        {
            try
            {
            	L2Skill skill =  _currentSkill.sets[i].getEnum("skillType", L2SkillType.class).makeSkill(_currentSkill.sets[i]);
            	skill.getSkillDes();
            	_currentSkill.currentSkills.add(i, skill );
            	count++;
            }
            catch (Exception e)
            {
            	Object [] temp = {_currentSkill.sets[i].getEnum("skillType", L2SkillType.class).makeSkill(_currentSkill.sets[i]).getIconId(),_currentSkill.sets[i].getEnum("skillType", L2SkillType.class).makeSkill(_currentSkill.sets[i]).getLevel(), e };
                _log.error("Skill i" + temp, Config.SERVER_ID, e );
                
            }
        }
       
	}
    
    public static void main(String args[])
    {
    	File file = new File("9000-9099.xml");
    	DocumentSkill ds = new DocumentSkill( file );
    	
    	ds.parse();
    	
    }
}
